// -*- c++ -*-
#ifndef TB_H
#define TB_H

#include "common.h"

module Tb {
 input:
  u11_t sum;
 output:
  u8_t d0, d1, d2, d3, d4, d5, d6, d7;
};

#endif

////////////////////////////////////////////////////////////////

#include "tb.h"
#include <iostream>
#include <stdexcept>

namespace {

class Rng {
public:
  Rng(unsigned int seed = 0x12345678) : m_seed(seed) {}
  u8_t get() {
    m_seed = m_seed * 1103515245u + 12345u;
    return (m_seed >> 15) & 0xff;
  }
private:
  unsigned int m_seed;
};

} // anonymous namespace

struct Tb {
  u11_t m_expect;
  bool  m_verified;
};

Tb() {
  Rng      rng;
  for (int i=0; i<10; ++i) {
    u8_t d0 = rng.get();
    u8_t d1 = rng.get();
    u8_t d2 = rng.get();
    u8_t d3 = rng.get();
    u8_t d4 = rng.get();
    u8_t d5 = rng.get();
    u8_t d6 = rng.get();
    u8_t d7 = rng.get();
    std::cout << "d0-d7 " << (int)d0 << ' ' << (int)d1 << ' ' << (int)d2 << ' ' << (int)d3
              << ' ' << (int)d4 << ' ' << (int)d5 << ' ' << (int)d6 << ' ' << (int)d7 << '\n';
    m_expect = d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7;
    m_verified = false;
    d0_out(d0);
    d1_out(d1);
    d2_out(d2);
    d3_out(d3);
    d4_out(d4);
    d5_out(d5);
    d6_out(d6);
    d7_out(d7);
    if (! m_verified)  throw std::runtime_error("no DUT output");
  }
}

Tb(sum) {
  std::cout << "sum " << (int)sum;
  if (sum != m_expect) {
    std::cout << " != " << (int)m_expect << '\n';
    throw std::runtime_error("curious DUT output");
  }
  std::cout << '\n';
  m_verified = true;
}
